#include <iostream>
#include <string>
using namespace std;

// 深拷贝与浅拷贝

// 浅拷贝：简单的赋值拷贝操作
// 深拷贝：在堆区重新申请空间，进行拷贝操作

class Person
{
public:
    int age;

    int* high;
    
    /*
        自定义类型，如果有指针变量，就必须写 拷贝构造 和 赋值运算符重载
        防止浅拷贝带来的错误
    */

    Person()
    {
        cout << "Person 默认构造函数的调用" << endl;
    }

    Person(int Age,int High)
    {
        age = Age;
        high = new int(High);
        cout << "Person 有参构造函数的调用" << endl;
    }

    //自己实现拷贝构造函数 解决浅拷贝带来的问题
    Person(const Person& p)
    {
        cout << "Person 拷贝构造函数调用" << endl;
        age = p.age;
        // high = p.high;  编译器默认选择这种代码，浅拷贝

        // 深拷贝操作
        high = new int(*p.high);
    }
    
    Person& operator=(const Person& p){
        cout << "Person 赋值运算符=调用" << endl;
        
        this->age = p.age;
        this->high = new int(*(p.high));
        return *this;
    }
    
    ~Person()
    {
        // 析构代码，将堆区开辟数据做释放操作
        if (high != NULL)
        {
            delete high;
        }
        cout << "Person 析构函数的调用" << endl;
    }
};

void test1()
{
    Person p1(18,180);

    cout << "p1的年龄为：" << p1.age
        << "  p1的身高为：" << *p1.high << endl;

    Person p2(p1);//浅拷贝，会对同一区域会重复释放

    cout << "p2的年龄为：" << p2.age
        << "  p2的身高为：" << *p2.high << endl;
        
    Person p3;
    p3 = p1;// 赋值运算
    
    cout << "p3的年龄为：" << p3.age
    << "  p3的身高为：" << *p3.high << endl;

}

int main()
{
    test1();
    
    return 0;
}